package com.power.sifa.correction.dao.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.aventrix.jnanoid.jnanoid.NanoIdUtils;
import com.plf.common.domain.YesNo;
import com.plf.core.common.dao.OffersetTransformers;
import com.power.sifa.correction.model.Crc_person;
import com.power.sifa.correction.model.Cre_record_ga;
import com.power.sifa.correction.model.Cre_warning;
import com.power.sifa.correction.model.enumeration.Tp_crc_rule;
import com.power.sifa.correction.model.enumeration.Tp_crc_ruleEnum;
import com.power.sifa.correction.model.enumeration.Tp_crc_userEnum;
import com.power.sifa.correction.model.pageInfo.Cre_record_gaPageInfo;
import com.power.sifa.statistics.model.vo.MarkPointVO;
import com.power.sifa.statistics.model.vo.MonitoringVO;
import org.hibernate.query.internal.NativeQueryImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;
import com.power.sifa.correction.dao.Cre_record_gaDaoCustom;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * 公安推送记录 持久层实现(hibernate)
 */

@Repository
public class Cre_record_gaDaoImpl implements Cre_record_gaDaoCustom {

    private static final Logger log = LoggerFactory.getLogger(Cre_record_gaDaoImpl.class);
    @Value("${power.file.http-schema:''}")
    private String httpSchema;
    @Value("${power.file.domain:''}")
    private String domain;

    private final EntityManager entityManager;

    public Cre_record_gaDaoImpl(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    @Override
    public Page getDayMonitor(Cre_record_gaPageInfo pageInfo) {
        List<Cre_record_ga> result = null;
        StringBuffer sql = new StringBuffer("SELECT * FROM ( " +
                "SELECT g.*, ROW_NUMBER() OVER (PARTITION BY g.perid ORDER BY g.rectime DESC) AS rn FROM cre_record_ga g WHERE 1 = 1 ");
        List<Object> paramsList = new ArrayList<>();
        int index = 1;

        if (ObjectUtil.isNotEmpty(pageInfo.getF_rectime())) {
            sql.append(" and g.rectime >= ?" + index++);
            paramsList.add(pageInfo.getF_rectime());
        }

        if (ObjectUtil.isNotEmpty(pageInfo.getF_rectime_01())) {
            sql.append(" and g.rectime <= ?" + index++);
            paramsList.add(pageInfo.getF_rectime_01());
        }

        sql.append(" ) AS subquery WHERE subquery.rn = 1");

        Query query = entityManager.createNativeQuery(sql.toString());
        query.unwrap(NativeQueryImpl.class).setResultTransformer(OffersetTransformers.ALIAS_TO_ENTITY_MAP);
        for (int i = 0; i <= paramsList.size() - 1; i++) {
            query.setParameter(i + 1, paramsList.get(i));
        }

        pageInfo.setAllcount(query.getResultList().size());
        if (pageInfo.getAllcount() < 0) {
            return null;
        }
        int pageStart = (pageInfo.getPageNumber() - 1) * pageInfo.getPageSize();
        List<Map<String, Object>> list = query.setFirstResult(pageStart).setMaxResults(pageInfo.getPageSize()).getResultList();
        if (CollectionUtil.isEmpty(list)) {
            return null;
        }
        result = JSON.parseArray(JSON.toJSONString(list), Cre_record_ga.class);
        Pageable pageable = PageRequest.of(pageInfo.getPageNumber() - 1, pageInfo.getPageSize());
        Page<Cre_record_ga> gas = new PageImpl<>(result, pageable, pageInfo.getAllcount());
        return gas;
    }

    @Override
    public List<MarkPointVO> getActionTrack(Cre_record_gaPageInfo pageInfo) {
        List<MarkPointVO> result = null;
        StringBuffer sql = new StringBuffer("select g.perid id, g.id gaid, g.rectime, g.latcamera as lat, g.lngcamera as lng, d.type, d.rulename " +
                "from cre_record_ga g left join cre_warning_detail d on d.gaid = g.id where 1 = 1");
        List<Object> paramsList = new ArrayList<>();
        int index = 1;

        if (ObjectUtil.isNotEmpty(pageInfo.getF_perid())) {
            sql.append(" and g.perid = ?" + index++);
            paramsList.add(pageInfo.getF_perid());
        }

        if (ObjectUtil.isNotEmpty(pageInfo.getF_rectime())) {
            sql.append(" and g.rectime >= ?" + index++);
            paramsList.add(pageInfo.getF_rectime());
        }

        if (ObjectUtil.isNotEmpty(pageInfo.getF_rectime_01())) {
            sql.append(" and g.rectime <= ?" + index++);
            paramsList.add(pageInfo.getF_rectime_01());
        }

        sql.append(" order by g.rectime");

        Query query = entityManager.createNativeQuery(sql.toString());
        query.unwrap(NativeQueryImpl.class).setResultTransformer(OffersetTransformers.ALIAS_TO_ENTITY_MAP);
        for (int i = 0; i <= paramsList.size() - 1; i++) {
            query.setParameter(i + 1, paramsList.get(i));
        }

        if (pageInfo.getAllcount() < 0) {
            return null;
        }
        List<Map<String, Object>> list = query.getResultList();
        if (CollectionUtil.isEmpty(list)) {
            return null;
        }
        for (Map<String, Object> map : list) {
//            map.put("id", pageInfo.getF_perid());
            map.put("traceId", NanoIdUtils.randomNanoId());
            if (ObjectUtil.isEmpty(map.get("type"))) {
                continue;
            }
            map.put("isViolation", YesNo.YES);
            Tp_crc_ruleEnum type = Tp_crc_ruleEnum.getById((Integer) map.get("type"));
            map.put("type", type.getDesc());
        }
        result = JSON.parseArray(JSON.toJSONString(list), MarkPointVO.class);
        return result;
    }

    @Override
    public List<MonitoringVO> getMonitoringList(Cre_record_gaPageInfo pageInfo) {
        StringBuffer sql = new StringBuffer("select g.id, g.perid, g.rectime, g.addr, p.name, p.gender, p.cardno, p.avatar, p.phone, " +
                "e.description as nation, p.crime, p.crctype, p.timelong, p.startdate, p.enddate, a.path as path, a.bucket as bucket " +
                "from cre_record_ga g " +
                "left join crc_person p on g.perid = p.id " +
                "left join ha_attachment a on a.id = p.avatar " +
                "left join ha_enumerationvalue e on p.nation = e.id " +
                "where 1 = 1");
        List<Object> paramsList = new ArrayList<>();
        int index = 1;

        if (ObjectUtil.isNotEmpty(pageInfo.getF_rectime())) {
            sql.append(" and g.rectime >= ?" + index++);
            paramsList.add(pageInfo.getF_rectime());
        }

        if (ObjectUtil.isNotEmpty(pageInfo.getF_rectime_01())) {
            sql.append(" and g.rectime <= ?" + index++);
            paramsList.add(pageInfo.getF_rectime_01());
        }

        Query query = entityManager.createNativeQuery(sql.toString());
        query.unwrap(NativeQueryImpl.class).setResultTransformer(OffersetTransformers.ALIAS_TO_ENTITY_MAP);
        for (int i = 0; i <= paramsList.size() - 1; i++) {
            query.setParameter(i + 1, paramsList.get(i));
        }
        log.warn("sql打印:{}", sql.toString());
        List<MonitoringVO> result = null;
        List<Map<String, Object>> list = query.getResultList();
        if (CollectionUtil.isEmpty(list)) {
            return null;
        }
        for (Map<String, Object> map : list) {
            String path = (String) map.get("path");
            String bucket = (String) map.get("bucket");
            String avatarUrl = httpSchema + domain + "/" + bucket + "/" + path;
            map.put("avatarUrl", avatarUrl);
            map.put("crctype_text", Tp_crc_userEnum.getTypeNameByValue((Integer) map.get("crctype")));
        }
        result = JSON.parseArray(JSON.toJSONString(list), MonitoringVO.class);
        return result;
    }
}